import { getShiftTypeStroke } from './shift-type-stroke';
import { setCurrentGroup } from './state';
import { unitWidth } from '../../config';

// 用于生成唯一ID的计数器
let shiftIdCounter = 0;

/**
 * 生成唯一的排班条ID
 * @param baseId 基础ID
 * @param suffix 后缀
 * @returns 唯一ID
 */
function generateUniqueShiftId(baseId: string, suffix: string): string {
  shiftIdCounter++;
  return `${baseId}_${suffix}_${shiftIdCounter}`;
}

// 添加调整大小的手柄
// const handleWidth = 8;

// 左侧调整手柄
// const leftHandle = new zrender.Rect({
//   shape: {
//     x: 0,
//     y: 0,
//     width: handleWidth,
//     height: SCHEDULE_BAR_HEIGHT, // 使用调整后的高度
//     r: [6, 0, 0, 6]
//   },
//   style: {
//     fill: 'transparent', // 默认透明
//     stroke: 'transparent', // 默认透明边框
//     lineWidth: 0
//   },
//   cursor: 'ew-resize',
//   z: 10,
//   draggable: false // 禁用手柄自身的拖拽
// });

// 右侧调整手柄
// const rightHandle = new zrender.Rect({
//   shape: {
//     x: width - handleWidth,
//     y: 0,
//     width: handleWidth,
//     height: SCHEDULE_BAR_HEIGHT, // 使用调整后的高度
//     r: [0, 6, 6, 0]
//   },
//   style: {
//     fill: 'transparent', // 默认透明
//     stroke: 'transparent', // 默认透明边框
//     lineWidth: 0
//   },
//   cursor: 'ew-resize',
//   z: 10,
//   draggable: false // 禁用手柄自身的拖拽
// });

// 设置调整手柄的事件
// setupResizeHandles(leftHandle, rightHandle, group, rect, shift, personIndex, shiftIndex, schedules, redrawChart, chartState);
// group.add(leftHandle);
// group.add(rightHandle);

/**
 * 设置调整大小手柄的事件
 */
export function setupResizeHandles(
  leftHandle: any,
  rightHandle: any,
  group: any,
  rect: any,
  shift: Shift,
  personIndex: number,
  shiftIndex: number,
  schedules: PersonSchedule[],
  redrawChart: RedrawChartFunction,
  chartState: ChartState,
) {
  const handleWidth = 8;
  let isResizing = false;
  let resizeType: 'left' | 'right' | null = null;
  let startX = 0;
  let originalStart = 0;
  let originalDuration = 0;

  // 设置手柄悬停效果
  const setupHandleHover = (handle: any) => {
    handle.on('mouseover', () => {
      if (!isResizing) {
        handle.attr({
          style: {
            fill: 'rgba(255, 255, 255, 0.8)',
            stroke: getShiftTypeStroke(shift.type),
            lineWidth: 2,
          },
        });
      }
    });

    handle.on('mouseout', () => {
      if (!isResizing) {
        handle.attr({
          style: {
            fill: 'transparent',
            stroke: 'transparent',
            lineWidth: 0,
          },
        });
      }
    });
  };

  // 应用悬停效果到两个手柄
  setupHandleHover(leftHandle);
  setupHandleHover(rightHandle);

  // 左侧手柄事件
  leftHandle.on('mousedown', (e: any) => {
    e.event.stopPropagation();
    e.event.preventDefault();
    isResizing = true;
    resizeType = 'left';
    startX = e.event.zrX;
    originalStart = shift.start;
    originalDuration = shift.duration;
    (group as any).resizing = true;

    // 禁用排班条组的拖拽功能
    group.attr('draggable', false);

    // 设置文档级别的光标样式
    document.body.style.cursor = 'ew-resize';

    // 设置当前操作组为调整大小模式
    setCurrentGroup(group);

    // 保持手柄高亮状态
    leftHandle.attr({
      style: {
        fill: 'rgba(255, 255, 255, 0.9)',
        stroke: getShiftTypeStroke(shift.type),
        lineWidth: 2,
      },
    });

    // 添加全局事件监听
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
  });

  // 右侧手柄事件
  rightHandle.on('mousedown', (e: any) => {
    e.event.stopPropagation();
    e.event.preventDefault();
    isResizing = true;
    resizeType = 'right';
    startX = e.event.zrX;
    originalStart = shift.start;
    originalDuration = shift.duration;
    (group as any).resizing = true;

    // 禁用排班条组的拖拽功能
    group.attr('draggable', false);

    // 设置文档级别的光标样式
    document.body.style.cursor = 'ew-resize';

    // 设置当前操作组为调整大小模式
    setCurrentGroup(group);

    // 保持手柄高亮状态
    rightHandle.attr({
      style: {
        fill: 'rgba(255, 255, 255, 0.9)',
        stroke: getShiftTypeStroke(shift.type),
        lineWidth: 2,
      },
    });

    // 添加全局事件监听
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
  });

  // 鼠标移动事件处理
  const handleMouseMove = (e: MouseEvent) => {
    if (!isResizing) {
      return;
    }

    // 设置文档级别的光标样式
    document.body.style.cursor = 'ew-resize';

    const deltaX = e.clientX - startX;

    if (resizeType === 'left') {
      // 左侧调整：基于像素的精确拖动
      const deltaUnits = deltaX / unitWidth;
      const newStart = Math.max(0, originalStart + deltaUnits);
      const newDuration = Math.max(1, originalDuration - (newStart - originalStart));

      // 更新排班数据（临时更新，用于UI显示）
      shift.start = newStart;
      shift.duration = newDuration;

      // 更新UI - 使用精确的像素宽度
      const newWidth = newDuration * unitWidth;
      rect.attr('shape', { width: newWidth });
      group.attr('x', chartState.chartStartX + newStart * unitWidth);

      // 更新手柄位置
      leftHandle.attr('shape', { x: 0 });
      rightHandle.attr('shape', { x: newWidth - handleWidth });
    } else if (resizeType === 'right') {
      // 右侧调整：基于像素的精确拖动
      const deltaUnits = deltaX / unitWidth;
      const newDuration = Math.max(1, originalDuration + deltaUnits);

      // 更新排班数据（临时更新，用于UI显示）
      shift.duration = newDuration;

      // 更新UI - 使用精确的像素宽度
      const newWidth = newDuration * unitWidth;
      rect.attr('shape', { width: newWidth });

      // 更新手柄位置
      rightHandle.attr('shape', { x: newWidth - handleWidth });
    }
  };

  // 鼠标释放事件处理
  const handleMouseUp = () => {
    if (!isResizing) {
      return;
    }

    // 获取当前的调整结果
    const currentStart = shift.start;
    const currentDuration = shift.duration;

    // 智能吸附到单元格
    let finalStart: number;
    let finalDuration: number;

    if (resizeType === 'left') {
      // 左侧调整：智能吸附开始时间
      const startFraction = currentStart - Math.floor(currentStart);
      if (startFraction >= 0.5) {
        // 超过一半，吸附到下一个单元格
        finalStart = Math.ceil(currentStart);
      } else {
        // 未超过一半，吸附到当前单元格
        finalStart = Math.floor(currentStart);
      }
      finalDuration = Math.max(1, originalDuration - (finalStart - originalStart));
    } else if (resizeType === 'right') {
      // 右侧调整：智能吸附结束时间
      finalStart = originalStart;
      const endTime = currentStart + currentDuration;
      const endFraction = endTime - Math.floor(endTime);
      if (endFraction >= 0.5) {
        // 超过一半，吸附到下一个单元格
        finalDuration = Math.ceil(endTime) - finalStart;
      } else {
        // 未超过一半，吸附到当前单元格
        finalDuration = Math.floor(endTime) - finalStart;
      }
      finalDuration = Math.max(1, finalDuration);
    } else {
      finalStart = currentStart;
      finalDuration = currentDuration;
    }

    isResizing = false;
    (group as any).resizing = false;
    resizeType = null;

    // 重新启用排班条组的拖拽功能
    group.attr('draggable', true);

    // 恢复文档级别的光标样式
    document.body.style.cursor = '';

    // 清除当前操作组
    setCurrentGroup(null);

    // 恢复手柄默认状态
    leftHandle.attr({
      style: {
        fill: 'transparent',
        stroke: 'transparent',
        lineWidth: 0,
      },
    });
    rightHandle.attr({
      style: {
        fill: 'transparent',
        stroke: 'transparent',
        lineWidth: 0,
      },
    });

    // 移除全局事件监听
    document.removeEventListener('mousemove', handleMouseMove);
    document.removeEventListener('mouseup', handleMouseUp);

    // 应用最终的吸附结果
    shift.start = finalStart;
    shift.duration = finalDuration;

    // 处理碰撞检测和自动重排
    handleResizeCollision(schedules, personIndex, shiftIndex, finalStart, finalDuration);

    // 重绘图表
    redrawChart(true);
  };
}

/**
 * 处理排班条碰撞检测和自动重排
 * @param schedules 人员排班数据
 * @param personIndex 当前调整的人员索引
 * @param shiftIndex 当前调整的排班索引
 * @param newStart 新的开始时间
 * @param newDuration 新的持续时间
 */
function handleResizeCollision(
  schedules: PersonSchedule[],
  personIndex: number,
  shiftIndex: number,
  newStart: number,
  newDuration: number,
) {
  const currentShift = schedules[personIndex].shifts[shiftIndex];
  const currentEnd = newStart + newDuration;

  // 更新当前排班条的位置和大小
  currentShift.start = newStart;
  currentShift.duration = newDuration;

  // 检测与同一人员其他排班条的冲突
  const personShifts = schedules[personIndex].shifts;
  const conflictingShifts: Array<{ shift: Shift; index: number }> = [];

  for (let i = 0; i < personShifts.length; i++) {
    if (i === shiftIndex) {
      continue;
    }

    const otherShift = personShifts[i];
    const otherEnd = otherShift.start + otherShift.duration;

    // 检查是否重叠
    if (!(currentEnd <= otherShift.start || newStart >= otherEnd)) {
      conflictingShifts.push({ shift: otherShift, index: i });
    }
  }

  // 处理冲突的排班条 - 计算被占据的区域并截取
  // 按索引倒序处理，避免索引变化影响后续处理
  conflictingShifts
    .sort((a, b) => b.index - a.index)
    .forEach(({ shift: conflictShift, index: conflictIndex }) => {
      handleResizeOccupiedArea(schedules[personIndex], conflictShift, conflictIndex, currentShift);
    });
}

/**
 * 处理被占据的区域 - 计算重叠区域并截取排班条
 * @param personSchedule 人员排班数据
 * @param conflictShift 被占据的排班条
 * @param conflictIndex 被占据排班条的索引
 * @param currentShift 当前调整的排班条
 */
function handleResizeOccupiedArea(
  personSchedule: PersonSchedule,
  conflictShift: Shift,
  conflictIndex: number,
  currentShift: Shift,
) {
  // 计算重叠区域
  const conflictStart = conflictShift.start;
  const conflictEnd = conflictStart + conflictShift.duration;
  const currentStart = currentShift.start;
  const currentEnd = currentStart + currentShift.duration;

  // 计算重叠区域
  const overlapStart = Math.max(conflictStart, currentStart);
  const overlapEnd = Math.min(conflictEnd, currentEnd);
  const overlapDuration = Math.max(0, overlapEnd - overlapStart);

  // 如果重叠时长等于被占据排班的时长，说明完全被占据
  if (overlapDuration >= conflictShift.duration) {
    console.log(`🗑️ 排班条 ${conflictShift.name} 完全被占据，删除`);
    personSchedule.shifts.splice(conflictIndex, 1);
    return;
  }

  // 计算截取后的排班条
  const remainingShifts: Shift[] = [];

  // 情况1: 重叠在排班条的前面部分
  if (overlapStart === conflictStart) {
    // 保留后半部分
    const remainingStart = overlapEnd;
    const remainingDuration = conflictEnd - remainingStart;

    if (remainingDuration > 0) {
      const remainingShift: Shift = {
        ...conflictShift,
        id: generateUniqueShiftId(conflictShift.id, 'part2'),
        start: remainingStart,
        duration: remainingDuration,
      };
      remainingShifts.push(remainingShift);
    }
  } else if (overlapEnd === conflictEnd) {
    // 情况2: 重叠在排班条的后面部分
    // 保留前半部分
    const remainingDuration = overlapStart - conflictStart;

    if (remainingDuration > 0) {
      const remainingShift: Shift = {
        ...conflictShift,
        id: generateUniqueShiftId(conflictShift.id, 'part1'),
        start: conflictStart,
        duration: remainingDuration,
      };
      remainingShifts.push(remainingShift);
    }
  } else {
    // 情况3: 重叠在排班条的中间部分
    // 保留前半部分
    const firstPartDuration = overlapStart - conflictStart;
    if (firstPartDuration > 0) {
      const firstPartShift: Shift = {
        ...conflictShift,
        id: generateUniqueShiftId(conflictShift.id, 'part1'),
        start: conflictStart,
        duration: firstPartDuration,
      };
      remainingShifts.push(firstPartShift);
    }

    // 保留后半部分
    const secondPartStart = overlapEnd;
    const secondPartDuration = conflictEnd - secondPartStart;
    if (secondPartDuration > 0) {
      const secondPartShift: Shift = {
        ...conflictShift,
        id: generateUniqueShiftId(conflictShift.id, 'part2'),
        start: secondPartStart,
        duration: secondPartDuration,
      };
      remainingShifts.push(secondPartShift);
    }
  }

  // 替换原排班条
  if (remainingShifts.length > 0) {
    // 删除原排班条
    personSchedule.shifts.splice(conflictIndex, 1);
    // 插入截取后的排班条
    personSchedule.shifts.splice(conflictIndex, 0, ...remainingShifts);
  } else {
    // 如果没有剩余部分，删除原排班条
    personSchedule.shifts.splice(conflictIndex, 1);
  }
}
